home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Pascal / Snippets / CopybitsSpeedPalette 1.0 / CopybitsSpeedPalette.p next >
Encoding:
Text File  |  1994-10-16  |  11.0 KB  |  378 lines  |  [TEXT/PJMM]

  1. (*--------------------------------------------------------------------------*)
  2. (*                                                                            *)
  3. (*        CopybitsSpeedPalette.                                                *)
  4. (*            by John Wang                                                    *)
  5. (*                                                                            *)
  6. (*        Description:    This program demostrates ways to increase copybits    *)
  7. (*            speed when using palettes.                                        *)
  8. (*                                                                            *)
  9. (*        Version:        1.0 Completed 11/12/91                                *)
  10. (*                                                                            *)
  11. (*--------------------------------------------------------------------------*)
  12.  
  13. {Think Pascal version by Ingemar 1994.}
  14. {• Pascal conversion.}
  15. {• Added two "draw" commands to draw several times with or without copying ctSeed. This makes the}
  16. {purpose of the demo *far* more obvious!}
  17. {• In other cases (updates, drag etc) when it used to do the demo drawing, it just draws once as a normal update.}
  18. {• Better zooming. The default now is the size where CopyBits is fastest.}
  19.  
  20. {The conclusion of the demo: For top speed, use matching color tables and copy the ctSeed from the}
  21. {screen device to the offscreens.}
  22.  
  23. program CopybitsSpeedPalette;
  24.  
  25.     uses
  26.         Palettes, QDOffscreen;
  27.  
  28.     const
  29.         kGestalttest = $A1AD;
  30.         kNoTrap = $A89F;
  31.  
  32.         appleID = 128;
  33.         appleMenu = 0;
  34.         aboutMeCommand = 1;
  35.  
  36.         fileID = 129;
  37.         drawNormalCommand = 1;
  38.         drawFastCommand = 2;
  39.         quitCommand = 4;
  40.  
  41.         pictID = 128;
  42.         clutID = 150;
  43.  
  44.         aboutMeDLOG = 128;
  45.         okButton = 1;
  46.  
  47. (*------------------------------------------------------*)
  48. (*    Global Variables.                                    *)
  49. (*------------------------------------------------------*)
  50.  
  51.     var
  52.         totalRect, minRect, winMinusScroll, initWindowSize: Rect;
  53.         myWindow: WindowPtr;
  54.         mycolors: CTabHandle;
  55.         srcPalette: PaletteHandle;
  56.         gDoneFlag: Boolean;
  57.         mymenu0, mymenu1: MenuHandle;
  58.         thePict: PicHandle;
  59.         offscreenGWorld: GWorldPtr;
  60.  
  61. (*------------------------------------------------------*)
  62. (*    showAboutMeDialog().                                *)
  63. (*------------------------------------------------------*)
  64.  
  65.     procedure ShowAboutMeDialog;
  66.         var
  67.             savePort: GrafPtr;
  68.             theDialog: DialogPtr;
  69.             itemHit: Integer;
  70.     begin
  71.         GetPort(savePort);
  72.         theDialog := GetNewDialog(aboutMeDLOG, nil, WindowPtr(-1));
  73.         SetPort(theDialog);
  74.  
  75.         repeat
  76.             ModalDialog(nil, itemHit);
  77.         until itemHit = okButton;
  78.  
  79.         CloseDialog(theDialog);
  80.  
  81.         SetPort(savePort);
  82.     end;
  83.  
  84. (*------------------------------------------------------*)
  85. (*    init().                                                *)
  86. (*------------------------------------------------------*)
  87.  
  88.     procedure Init;
  89.         var
  90.             tempRgn: RgnHandle;
  91.             baseRect: Rect;
  92.             err: OSErr;
  93.             QDfeature, OSfeature: LongInt;
  94.             saveGD: GDHandle;
  95.             savePort: CGrafPtr;
  96.     begin
  97. (*    Initialize Managers.    *)
  98. {$IFC UNDEFINED THINK_PASCAL}
  99.         InitGraf(qd.thePort);
  100.         FlushEvents(everyEvent, 0);
  101.         InitWindows;
  102.         InitDialogs(nil);
  103. {$ENDC}
  104.         InitCursor;
  105.  
  106.     (*    Set up menus.    *)
  107.         mymenu0 := GetMenu(appleID);
  108.         AddResMenu(mymenu0, 'DRVR');
  109.         InsertMenu(mymenu0, 0);
  110.         mymenu1 := GetMenu(fileID);
  111.         InsertMenu(mymenu1, 0);
  112.         DrawMenuBar;
  113.         gDoneFlag := FALSE;
  114.         thePict := GetPicture(pictID);
  115.         if (thePict = nil) then
  116.             gDoneFlag := TRUE;
  117.  
  118.     (*    Use Gestalt to find if 32-bit QuickDraw is available.    *)
  119.         if ((GetTrapAddress(kGestalttest) <> GetTrapAddress(kNoTrap))) then
  120.             begin
  121.                 err := Gestalt(gestaltQuickdrawVersion, QDfeature);
  122.                 if err <> noErr then
  123.                     gDoneFlag := TRUE;
  124.                 err := Gestalt(gestaltSystemVersion, OSfeature);
  125.                 if err <> noErr then
  126.                     gDoneFlag := TRUE;
  127.                 if not gDoneFlag then
  128.                     if (BitAnd(QDfeature, $0f00) <> $0200) and (OSfeature < $0605) then
  129.                         gDoneFlag := TRUE;
  130.             end
  131.         else
  132.             gDoneFlag := TRUE;
  133.  
  134.     (*    Set Rects.    *)
  135.         SetRect(baseRect, 40, 60, 472, 282);
  136.         SetRect(winMinusScroll, baseRect.left - 40, baseRect.top - 60, baseRect.right - 60, baseRect.bottom - 80);
  137. {SetRect(initWindowSize, winMinusScroll.left, winMinusScroll.top, winMinusScroll.right, winMinusScroll.bottom);}
  138.         initWindowSize := winMinusScroll;
  139.         tempRgn := GetGrayRgn;
  140.         HLock(Handle(tempRgn));
  141.         totalRect := tempRgn^^.rgnBBox;
  142.         SetRect(minRect, 80, 80, tempRgn^^.rgnBBox.right - 40, tempRgn^^.rgnBBox.bottom - 40);
  143.         HUnlock(Handle(tempRgn));
  144.  
  145.     (*    Open window and set up picture.    *)
  146.         GetGWorld(savePort, saveGD);
  147.         mycolors := GetCTable(clutID);
  148.         mycolors^^.ctFlags := BitOr(mycolors^^.ctFlags, $4000);
  149.  
  150.         myWindow := NewCWindow(nil, baseRect, '', TRUE, zoomDocProc, WindowPtr(-1), TRUE, 150);
  151.         SetGWorld(CGrafPtr(myWindow), saveGD);
  152.         DrawGrowIcon(myWindow);
  153.  
  154.         srcPalette := NewPalette((mycolors^^.ctSize) + 1, mycolors, pmTolerant + pmExplicit + pmAnimated, 0);
  155.         SetPalette(myWindow, srcPalette, TRUE);
  156.  
  157.         GetGWorld(savePort, saveGD);
  158.         err := NewGWorld(offscreenGWorld, 8, initWindowSize, mycolors, nil, []);
  159.         if err <> noErr then
  160.             begin
  161.                 SysBeep(1);
  162.                 halt;{Debugger;}
  163.             end;{Probably out of memory}
  164.         SetGWorld(offscreenGWorld, nil);
  165.         EraseRect(initWindowSize);
  166.         DrawPicture(thePict, initWindowSize);
  167.         SetGWorld(savePort, saveGD);
  168.     end;
  169.  
  170. (*------------------------------------------------------*)
  171. (*    draw.                                                *)
  172. (*------------------------------------------------------*)
  173.  
  174.     procedure Draw (fast: Boolean);
  175.         var
  176. {    black, white: RGBColor;}
  177.             before, delay: LongInt;
  178.             theString: Str255;
  179.             screensDevice: GDHandle;
  180.             area: Rect;
  181.             saveSeed: Longint;
  182.     begin
  183. {   black.red := 0;}
  184. {  black.green := 0;}
  185. {  black.blue := 0;}
  186. {  white.red := -1;}
  187. {  white.green := -1;}
  188. {  white.blue := -1;}
  189. { }
  190. {RGBForeColor(black);}
  191. {RGBBackColor(White);}
  192.  
  193.         ForeColor(blackColor);
  194.         BackColor(whiteColor);
  195.  
  196.         if fast then
  197.             begin    (* This is the only change made to support a faster copybits on one screen.}
  198.         {ctFlags is still set above. *)
  199.                 area := winMinusScroll;
  200.                 LocalToGlobal(area.topLeft);
  201.                 LocalToGlobal(area.botRight);
  202.                 screensDevice := GetMaxDevice(area);
  203.                 saveSeed := offscreenGWorld^.portPixMap^^.pmTable^^.ctSeed;
  204.                 if screensDevice <> nil then
  205.                     offscreenGWorld^.portPixMap^^.pmTable^^.ctSeed := screensDevice^^.gdPMap^^.pmTable^^.ctSeed;
  206.             end;
  207.  
  208.         before := TickCount;
  209.  
  210.         EraseRect(winMinusScroll);
  211.         CopyBits(GrafPtr(offscreenGWorld)^.portBits, myWindow^.portBits, initWindowSize, winMinusScroll, srcCopy, nil);
  212.         EraseRect(winMinusScroll);
  213.         CopyBits(GrafPtr(offscreenGWorld)^.portBits, myWindow^.portBits, initWindowSize, winMinusScroll, srcCopy, nil);
  214.         EraseRect(winMinusScroll);
  215.         CopyBits(GrafPtr(offscreenGWorld)^.portBits, myWindow^.portBits, initWindowSize, winMinusScroll, srcCopy, nil);
  216.         EraseRect(winMinusScroll);
  217.         CopyBits(GrafPtr(offscreenGWorld)^.portBits, myWindow^.portBits, initWindowSize, winMinusScroll, srcCopy, nil);
  218.         EraseRect(winMinusScroll);
  219.         CopyBits(GrafPtr(offscreenGWorld)^.portBits, myWindow^.portBits, initWindowSize, winMinusScroll, srcCopy, nil);
  220.         delay := TickCount - before;
  221.  
  222. {Erase the space where the text goes.}
  223.         SetPort(myWindow);
  224.         area := myWindow^.portRect;
  225.         area.top := area.bottom - 14;
  226.         area.right := area.right - 15;
  227.         EraseRect(area);
  228. {Now tell us how fast it was.}
  229.         MoveTo(5, myWindow^.portRect.bottom - 3);
  230.         DrawString(stringof('5 EraseRect+CopyBits in ', delay : 0, ' ticks.'));
  231.  
  232.         if fast then
  233.             offscreenGWorld^.portPixMap^^.pmTable^^.ctSeed := saveSeed;
  234.     end;
  235.  
  236. (*------------------------------------------------------*)
  237. (*    doCommand().                                        *)
  238. (*------------------------------------------------------*)
  239.  
  240.     procedure DoCommand (mResult: Longint);
  241.         var
  242.             theMenu, theItem: Integer;
  243.             daName: Str255;
  244.             savePort: GrafPtr;
  245.     begin
  246.         theItem := LoWord(mResult);
  247.         theMenu := HiWord(mResult);
  248.  
  249.         case theMenu of
  250.             appleID: 
  251.                 if theItem = aboutMeCommand then
  252.                     ShowAboutMeDialog
  253.                 else
  254.                     begin
  255.                         GetItem(mymenu0, theItem, daName);
  256.                         GetPort(savePort);
  257.                         if OpenDeskAcc(daName) <> noErr then
  258.                             ;
  259.                         SetPort(savePort);
  260.                     end;
  261.             fileID: 
  262.                 case theItem of
  263.                     drawNormalCommand: 
  264.                         Draw(false);
  265.                     drawFastCommand: 
  266.                         Draw(true);
  267.                     quitCommand: 
  268.                         gDoneFlag := TRUE;
  269.                     otherwise
  270.                 end; {case theItem}
  271.         end;{case}
  272.         HiliteMenu(0);
  273.     end; {DoCommand}
  274.  
  275. (*------------------------------------------------------*)
  276. (*    main().                                                *)
  277. (*------------------------------------------------------*)
  278.  
  279.     var
  280.         key: char;
  281.         track: Boolean;
  282.         growResult: LongInt;
  283.         myEvent: EventRecord;
  284.         whichWindow: WindowPtr;
  285.         yieldTime: Integer;
  286.  
  287. {main}
  288. begin
  289.     Init;
  290.     yieldTime := 0;
  291.     while true do
  292.         begin
  293.             if (gDoneFlag) then
  294.                 ExitToShell;
  295.  
  296.             if WaitNextEvent(everyEvent, myEvent, yieldTime, nil) then
  297.                 case myEvent.what of
  298.                     mouseDown: 
  299.                         case FindWindow(myEvent.where, whichWindow) of
  300.                             inSysWindow: 
  301.                                 SystemClick(myEvent, whichWindow);
  302.                             inMenuBar: 
  303.                                 DoCommand(MenuSelect(myEvent.where));
  304.                             inContent: 
  305.                                 ;
  306.                             inDrag: 
  307.                                 begin
  308.                                     DragWindow(whichWindow, myEvent.where, totalRect);
  309. {Draw;}
  310.                                     DrawGrowIcon(whichWindow);
  311.                                 end;
  312.                             inGrow: 
  313.                                 begin
  314.                                     growResult := GrowWindow(whichWindow, myEvent.where, minRect);
  315.                                     SizeWindow(whichWindow, LoWord(growResult), HiWord(growResult), TRUE);
  316.                                     EraseRect(whichWindow^.portRect);
  317.                                     InvalRect(whichWindow^.portRect);
  318.                                     SetRect(winMinusScroll, whichWindow^.portRect.left, whichWindow^.portRect.top, whichWindow^.portRect.right - 20, whichWindow^.portRect.bottom - 20);
  319.                                     DrawGrowIcon(whichWindow);
  320.                                 end;
  321.                             inGoAway: 
  322.                                 if TrackGoAway(whichWindow, myEvent.where) then
  323.                                     begin
  324.                                         CloseWindow(whichWindow);
  325.                                         gDoneFlag := TRUE;
  326.                                     end;
  327.                             inZoomIn: 
  328.                                 if TrackBox(whichWindow, myEvent.where, inZoomIn) then
  329.                                     begin
  330.                                         ZoomWindow(whichWindow, inZoomIn, TRUE);
  331.                                         EraseRect(whichWindow^.portRect);
  332.                                         InvalRect(whichWindow^.portRect);
  333.                                         SetRect(winMinusScroll, whichWindow^.portRect.left, whichWindow^.portRect.top, whichWindow^.portRect.right - 20, whichWindow^.portRect.bottom - 20);
  334.                                         DrawGrowIcon(whichWindow);
  335.                                     end;
  336.                             inZoomOut: 
  337.                                 if TrackBox(whichWindow, myEvent.where, inZoomOut) then
  338.                                     begin
  339.                                         SizeWindow(whichWindow, initWindowSize.right - initWindowSize.left + 20, initWindowSize.bottom - initWindowSize.top + 20, true);
  340. {ZoomWindow(whichWindow, inZoomOut, TRUE);}
  341.                                         EraseRect(whichWindow^.portRect);
  342.                                         InvalRect(whichWindow^.portRect);
  343.                                         SetRect(winMinusScroll, whichWindow^.portRect.left, whichWindow^.portRect.top, whichWindow^.portRect.right - 20, whichWindow^.portRect.bottom - 20);
  344.                                         DrawGrowIcon(whichWindow);
  345.                                     end;
  346.                             otherwise
  347.                         end; {case FindWindow}
  348.                     keyDown, autoKey: 
  349.                         begin
  350.                             key := Char(BitAnd(myEvent.message, charCodeMask));
  351.                             if BitAnd(myEvent.modifiers, cmdKey) <> 0 then
  352.                                 if (myEvent.what = keyDown) then
  353.                                     DoCommand(MenuKey(key));
  354.                         end;
  355.                     updateEvt: 
  356.                         if WindowPtr(myEvent.message) = myWindow then
  357.                             begin
  358.                                 BeginUpdate(myWindow);
  359.                                 CopyBits(GrafPtr(offscreenGWorld)^.portBits, myWindow^.portBits, initWindowSize, winMinusScroll, srcCopy, nil);
  360.                                 DrawGrowIcon(myWindow);
  361.                                 EndUpdate(myWindow);
  362.                             end;
  363.                     diskEvt: 
  364.                         ;
  365.                     activateEvt: 
  366.                         ;
  367.                     app4Evt: 
  368.                         if (BSL(myEvent.message, 31) = 0) then
  369.                             yieldTime := 30
  370.                         else
  371.                             begin
  372.                                 yieldTime := 0;
  373.                                 SetPort(myWindow);
  374.                             end;
  375.                     otherwise
  376.                 end; {case}
  377.         end; {while true}
  378. end.